﻿/**
 * GoText Palm: A program that allows to send text messages over the internet.
 *  Copyright (C) 2008 Nicola 'Gawaine' Racco
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using GoTextPalm.Core;
using GoTextPalm.Core.Localization;
using GoTextPalm.Core.Data;
using GoTextPalm.Core.Persistence;

namespace GoTextPalm.Gui
{
    public partial class ConfigForm : LocalizedForm
    {
        delegate void Func<T>(T t);
        delegate void Func();

        private Logic logic;

        public ConfigForm()
        {
            //+Handling logic events
            logic = new Logic();
            logic.ErrorCausedEvent += new Logic.ErrorCaused(Logic_ErrorCaused);
            logic.SaveProcedureClosedEvent += new Logic.SaveProcedureClosed(Logic_SaveProcedureClosed);
            logic.StatusTextChangedEvent += new Logic.StatusTextChanged(Logic_StatusTextChanged);
            logic.LoadedDataEvent += new Logic.LoadedData(Logic_LoadedData);
            //-
            InitializeComponent();
            header.Text = "Configuration";
            cmbSavPolicy.Items.Add(Utility.Tr("ConfigForm_saveBefore", "Before sending"));
            cmbSavPolicy.Items.Add(Utility.Tr("ConfigForm_saveAfter", "After a successfully sending"));
            AddMenusToDictionary();
            UpdateResources();
        }

        protected override void AddMenusToDictionary()
        {
            AddMenuToDictionary(mnuSave, "mnuSave");
        }

        private void ConfigForm_Load(object sender, EventArgs e)
        {
            if (customInputPanel.SipSupported)
            {
                customInputPanel.Screen = screen;
                customInputPanel.Refresh();
            }
            lblLang.Enabled = cmbLang.Enabled = chkPrefix.Enabled = txtPrefix.Enabled = mnuSave.Enabled = false;
            new Thread(new ThreadStart(logic.LoadProcedure)).Start();
        }

        private void chkPrefix_CheckStateChanged(object sender, EventArgs e)
        {
            txtPrefix.Visible = chkPrefix.Checked;
        }

        private void chkSaving_CheckStateChanged(object sender, EventArgs e)
        {
            pnlSaving.Visible = chkSaving.Checked;
        }

        private void mnuSave_Click(object sender, EventArgs e)
        {
            if (cmbLang.SelectedItem == null)
                MessageBox.Show(Utility.Tr("ConfigForm_needlng", 
                    "Field 'Language' is needed"), header.Text, 
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation, 
                    MessageBoxDefaultButton.Button1);
            if (chkPrefix.Checked && txtPrefix.Text == String.Empty)
                MessageBox.Show(Utility.Tr("ConfigForm_needprefix",
                    "Field 'Prefix' is needed"), header.Text, MessageBoxButtons.OK, 
                    MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
            if (chkSaving.Checked && !rdSavAsk.Checked && !rdSavAuto.Checked
                && cmbSavPolicy.SelectedItem == null)
                MessageBox.Show(Utility.Tr("ConfigForm_needsav",
                    "When enabling Saving Management all subfields are needed"), 
                    header.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation, 
                    MessageBoxDefaultButton.Button1);
            lblLang.Enabled = cmbLang.Enabled = chkPrefix.Enabled = txtPrefix.Enabled = mnuSave.Enabled = false;
            logic.Prefix = txtPrefix.Text;
            logic.Language = (Language)cmbLang.SelectedItem;
            logic.savingMessagesEnabled = chkSaving.Checked ? (rdSavAuto.Checked ? 0 : 1) : -1;
            logic.savingPolicy = cmbSavPolicy.SelectedIndex;
            logic.savingLastMessage = chkLast.Checked;
            new Thread(new ThreadStart(logic.SaveProcedure)).Start();
        }


        public void Logic_LoadedData(String prefix, Language lang, int savingEnabled, int savingPolicy, bool lastSavingMessage)
        {
            if (InvokeRequired)
            {
                Logic.LoadedData func = Logic_LoadedData;
                if (prefix == null)
                    prefix = String.Empty;
                Invoke(func, prefix, lang, savingEnabled, savingPolicy, lastSavingMessage);
                return;
            }
            foreach (Language lng in Languages.Langs)
                cmbLang.Items.Add(lng);
            cmbLang.SelectedItem = lang;
            if (prefix != null && prefix != String.Empty)
            {
                chkPrefix.Checked = true;
                txtPrefix.Text = prefix;
            }
            if (savingEnabled == -1)
            {
                rdSavAuto.Checked = true;
                chkSaving.Checked = false;
            }
            else
            {
                chkSaving.Checked = true;
                if (savingEnabled == 0)
                    rdSavAuto.Checked = true;
                else
                    rdSavAsk.Checked = true;
            }
            chkLast.Checked = lastSavingMessage;
            cmbSavPolicy.SelectedIndex = savingPolicy;
            stsBar.Visible = stsBar.ProgressStarted = false;
            lblLang.Enabled = cmbLang.Enabled = chkPrefix.Enabled = txtPrefix.Enabled = mnuSave.Enabled = true;
        }

        public void Logic_StatusTextChanged(String text)
        {
            if (InvokeRequired)
            {
                Logic.StatusTextChanged func = Logic_StatusTextChanged;
                Invoke(func, text);
                return;
            }
            if (!stsBar.Visible)
                stsBar.Visible = stsBar.ProgressStarted = true;
            stsBar.Text = text;
        }

        public void Logic_ErrorCaused(String text)
        {
            if (InvokeRequired)
            {
                Logic.ErrorCaused func = Logic_ErrorCaused;
                Invoke(func, text);
                return;
            }
            MessageBox.Show(text, header.Text, MessageBoxButtons.OK,
                MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
        }

        public void Logic_SaveProcedureClosed(bool aborted)
        {
            if (InvokeRequired)
            {
                Logic.SaveProcedureClosed func = Logic_SaveProcedureClosed;
                Invoke(func, aborted);
                return;
            }
            stsBar.Visible = stsBar.ProgressStarted = false;
            lblLang.Enabled = cmbLang.Enabled = chkPrefix.Enabled = txtPrefix.Enabled = mnuSave.Enabled = true;
            if (!aborted)
                Close();
        }

        private class Logic
        {
            public delegate void StatusTextChanged(String text);
            public event StatusTextChanged StatusTextChangedEvent;

            public delegate void SaveProcedureClosed(bool aborted);
            public event SaveProcedureClosed SaveProcedureClosedEvent;

            public delegate void ErrorCaused(String text);
            public event ErrorCaused ErrorCausedEvent;

            public delegate void LoadedData(String prefix, Language language, 
                int savingEnabled, int savingPolicy, bool savingLastMessage);
            public event LoadedData LoadedDataEvent;

            public void LoadProcedure()
            {
                FireStatusChangedEvent(Utility.Tr("ConfigForm_sts1", "Loading Configuration ..."));
                Language lang = Languages.GetLanguage(DBConfig.get("lang"));
                String prefix = DBConfig.get("prefix");
                int savingEnabled = ServiceLogic.GetSavingMessagesEnabled();
                int savingPolicy = ServiceLogic.GetSavingPolicy();
                bool lastSavingMessage = ServiceLogic.GetSavingLastMessageEnabled();
                FireLoadedDataEvent(prefix, lang, savingEnabled, savingPolicy, lastSavingMessage);
            }

            public void FireLoadedDataEvent(String prefix, Language language, 
                int savingEnabled, int savingPolicy, bool savingLastMessage)
            {
                if (LoadedDataEvent != null)
                    LoadedDataEvent(prefix, language, savingEnabled, savingPolicy, savingLastMessage);
            }

            public String Prefix;
            public Language Language;
            public int savingMessagesEnabled, savingPolicy;
            public Boolean savingLastMessage;

            public void SaveProcedure()
            {
                FireStatusChangedEvent(Utility.Tr("ConfigForm_sts2", "Saving Configuration ..."));

                try
                {
                    DBConfig.set("prefix", Prefix);
                    ServiceLogic.SetLanguage(Language);
                    ServiceLogic.SetSavingMessagesEnabled(savingMessagesEnabled);
                    ServiceLogic.SetSavingPolicy(savingPolicy);
                    ServiceLogic.SetSavingLastMessageEnabled(savingLastMessage);
                    FireSaveProcedureClosedEvent(false);
                }
                catch (Exception ex)
                {
                    FireErrorCausedEvent(String.Format(
                        Utility.Tr("ConfigForm_cantsave", 
                        "Cannot save configuration data: {0}"), ex.Message));
                    FireSaveProcedureClosedEvent(true);
                }
            }

            private void FireErrorCausedEvent(String text)
            {
                if (ErrorCausedEvent != null)
                    ErrorCausedEvent(text);
            }

            private void FireStatusChangedEvent(String text)
            {
                if (StatusTextChangedEvent != null)
                    StatusTextChangedEvent(text);
            }

            private void FireSaveProcedureClosedEvent(bool aborted)
            {
                if (SaveProcedureClosedEvent != null)
                    SaveProcedureClosedEvent(aborted);
            }
        }
    }
}